<template>
  <div class="vditor-container" ref="parentRef">
    <div ref="vditorContainerRef"></div>
    <div
      ref="draggableRef"
      @mousedown.prevent="handleMouseDown"
      :style="{ top: `${dragY}px`, left: `${dragX}px` }"
      class="quick-button"
    >
      <el-button
        title="快速保存"
        :type="isShowQuickSave ? 'primary' : 'success'"
        :icon="isShowQuickSave ? Edit : Check"
        circle
      />
    </div>
    <!-- 添加或修改文章配置对话框 -->
    <el-dialog :title="title" v-model="open" width="600px" apprulesend-to-body>
      <el-form :model="form" :rules="rules" ref="publishRef" label-width="80px">
        <el-row>
          <el-col :span="24">
            <el-form-item label="文章标题" prop="title">
              <el-input
                v-model="form.title"
                placeholder="请输入文章标题"
                maxlength="30"
              />
            </el-form-item>
          </el-col>
          <el-col :span="24">
            <el-form-item label="文章分类" prop="categoryIdList">
              <el-select
                style="width: 100%"
                v-model="form.categoryIdList"
                filterable
                multiple
                placeholder="请选择"
              >
                <el-option
                  v-for="categoryItem in categoryOptions"
                  :key="categoryItem.categoryId"
                  :label="categoryItem.categoryName"
                  :value="String(categoryItem.categoryId)"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="文章标签" prop="tagIdList">
              <el-select
                style="width: 100%"
                v-model="form.tagIdList"
                filterable
                multiple
                placeholder="请选择"
              >
                <el-option
                  v-for="tagItem in tagOptions"
                  :key="tagItem.tagId"
                  :label="tagItem.tagName"
                  :value="String(tagItem.tagId)"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="handleClickPublish"
            >确 定</el-button
          >
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
// @ts-ignore
import Vditor from "vditor";
import { onMounted, ref } from "vue";
import "vditor/dist/index.css";
import { toRef } from "vue";
import {
  listArticle,
  addArticle,
  getArticle,
  updateArticle,
} from "@/api/blog/article";
import {
  Check,
  Delete,
  Edit,
  Message,
  Search,
  Star,
} from "@element-plus/icons-vue";
import { calcColumnStyle } from "element-plus/es/components/table-v2/src/composables/utils.mjs";
import { listCategory } from "@/api/blog/category";
import { listTag } from "@/api/blog/tag";

const categoryOptions = ref<any>([]);
const tagOptions = ref<any>([]);
const getOptions = async () => {
  try {
    const res = await listCategory(); // 假设 listCategory() 返回一个 Promise
    categoryOptions.value = res.data; // 使用 .value 来更新 ref 的值

    const tagOptionsRes = await listTag(); // 假设 listCategory() 返回一个 Promise
    tagOptions.value = tagOptionsRes.data; // 使用 .value 来更新 ref 的值
  } catch (error) {
    console.error("Error fetching category options:", error); // 错误处理
  }
};
getOptions();

const { proxy } = getCurrentInstance();
const { category, tag } = proxy.useSelect("category", "tag");
const open = ref(false);
const isShowQuickSave = ref(true);
const form = ref({
  categoryIdList: [],
  tagIdList: [],
  title: "",
  contentHtml: "",
  contentMd: "",
  articleId: "",
});
const title = ref("");
const rules = ref({
  title: [
    { required: true, message: "文章名称不能为空", trigger: "blur" },
    {
      min: 2,
      max: 20,
      message: "文章名称长度必须介于 2 和 20 之间",
      trigger: "blur",
    },
  ],
});

const props = defineProps({ articleId: Number });
const article = ref<any>({});

const vditorContainerRef = ref(null);
let vditor: any;

const init = async () => {
  await getUpdateInfo();
  vditor = new Vditor(vditorContainerRef.value, {
    height: "100%",
    mode: "wysiwyg", // 显示预览内容
    placeholder: "请输入内容...",
    toolbar: [
      "emoji",
      "headings",
      "bold",
      "italic",
      "strike",
      "link",
      "|",
      "list",
      "ordered-list",
      "check",
      "outdent",
      "indent",
      "|",
      "quote",
      "line",
      "code",
      "inline-code",
      "insert-before",
      "insert-after",
      "|",
      //"upload",
      // "record",
      {
        //自定义上传
        hotkey: "",
        name: "upload",
        // tipPosition: "s",
        tip: "上传图片",
        className: "right",
      },

      "table",
      "|",
      "undo",
      "redo",
      "|",
      // "fullscreen",
      "edit-mode",
      {
        name: "more",
        toolbar: [
          //"both",
          "code-theme",
          "content-theme",
          "export",
          "outline",
          "preview",
          //"devtools",
          // "info",
          //"help",
        ],
      },
      {
        name: "sponsor",
        tipPosition: "s",
        tip: "发布",
        className: "right",
        icon: '<svg t="1589994565028" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2808" width="32" height="32"><path d="M506.6 423.6m-29.8 0a29.8 29.8 0 1 0 59.6 0 29.8 29.8 0 1 0-59.6 0Z" fill="#0F0F0F" p-id="2809"></path><path d="M717.8 114.5c-83.5 0-158.4 65.4-211.2 122-52.7-56.6-127.7-122-211.2-122-159.5 0-273.9 129.3-273.9 288.9C21.5 562.9 429.3 913 506.6 913s485.1-350.1 485.1-509.7c0.1-159.5-114.4-288.8-273.9-288.8z" fill="#FAFCFB" p-id="2810"></path><path d="M506.6 926c-22 0-61-20.1-116-59.6-51.5-37-109.9-86.4-164.6-139-65.4-63-217.5-220.6-217.5-324 0-81.4 28.6-157.1 80.6-213.1 53.2-57.2 126.4-88.8 206.3-88.8 40 0 81.8 14.1 124.2 41.9 28.1 18.4 56.6 42.8 86.9 74.2 30.3-31.5 58.9-55.8 86.9-74.2 42.5-27.8 84.3-41.9 124.2-41.9 79.9 0 153.2 31.5 206.3 88.8 52 56 80.6 131.7 80.6 213.1 0 103.4-152.1 261-217.5 324-54.6 52.6-113.1 102-164.6 139-54.8 39.5-93.8 59.6-115.8 59.6zM295.4 127.5c-72.6 0-139.1 28.6-187.3 80.4-47.5 51.2-73.7 120.6-73.7 195.4 0 64.8 78.3 178.9 209.6 305.3 53.8 51.8 111.2 100.3 161.7 136.6 56.1 40.4 88.9 54.8 100.9 54.8s44.7-14.4 100.9-54.8c50.5-36.3 108-84.9 161.7-136.6 131.2-126.4 209.6-240.5 209.6-305.3 0-74.9-26.2-144.2-73.7-195.4-48.2-51.9-114.7-80.4-187.3-80.4-61.8 0-127.8 38.5-201.7 117.9-2.5 2.6-5.9 4.1-9.5 4.1s-7.1-1.5-9.5-4.1C423.2 166 357.2 127.5 295.4 127.5z" fill="#141414" p-id="2811"></path><path d="M353.9 415.6m-33.8 0a33.8 33.8 0 1 0 67.6 0 33.8 33.8 0 1 0-67.6 0Z" fill="#0F0F0F" p-id="2812"></path><path d="M659.3 415.6m-33.8 0a33.8 33.8 0 1 0 67.6 0 33.8 33.8 0 1 0-67.6 0Z" fill="#0F0F0F" p-id="2813"></path><path d="M411.6 538.5c0 52.3 42.8 95 95 95 52.3 0 95-42.8 95-95v-31.7h-190v31.7z" fill="#5B5143" p-id="2814"></path><path d="M506.6 646.5c-59.6 0-108-48.5-108-108v-31.7c0-7.2 5.8-13 13-13h190.1c7.2 0 13 5.8 13 13v31.7c0 59.5-48.5 108-108.1 108z m-82-126.7v18.7c0 45.2 36.8 82 82 82s82-36.8 82-82v-18.7h-164z" fill="#141414" p-id="2815"></path><path d="M450.4 578.9a54.7 27.5 0 1 0 109.4 0 54.7 27.5 0 1 0-109.4 0Z" fill="#EA64F9" p-id="2816"></path><path d="M256 502.7a32.1 27.5 0 1 0 64.2 0 32.1 27.5 0 1 0-64.2 0Z" fill="#EFAFF9" p-id="2817"></path><path d="M703.3 502.7a32.1 27.5 0 1 0 64.2 0 32.1 27.5 0 1 0-64.2 0Z" fill="#EFAFF9" p-id="2818"></path></svg>',
        // icon: "<div>保存<div/>",
        click() {
          openSaveDialog();
        },
      },
    ],
    toolbarConfig: {
      pin: true,
    },
    cache: {
      enable: false,
    },
    after: () => {
      vditor.setValue(article.value?.contentMd || "");
    },
    // 其他 Vditor 配置选项
    upload: {
      url: "url", // sm.ms 图床的上传接口地址
      accept: "image/*", // 限制上传的文件类型为图片
      withCredentials: true, // 不携带跨域请求的凭据
      headers: {},
      // 自定义上传成功的回调函数
      success: (
        editor: { insertValue: (arg0: string) => void },
        msg: string
      ) => {
        const data = JSON.parse(msg);
        if (data.code === "success") {
          // 上传成功，将图片插入到编辑器中
          editor.insertValue(`![${data.data.filename}](${data.data.url})`);
        } else {
          console.error("上传失败1:", data.message);
        }
      },
      // 自定义上传失败的回调函数
      error: (msg: any) => {
        console.error("上传失败2:", msg);
      },
    },
  });
};

async function getUpdateInfo() {
  if (props.articleId !== undefined && props.articleId != 0) {
    let response = await getArticle({ id: props.articleId });
    article.value = response.data;
    form.value = response.data;
  }
}

const getContent = async () => {
  if (vditor) {
    form.value.contentMd = vditor.getValue();
    form.value.contentHtml = vditor.getHTML();
  } else {
    console.error("Vditor 实例尚未初始化");
  }
};

/** 打开保存弹窗 */
function openSaveDialog() {
  if (article.value?.articleId) {
    //修改
    handleUpdate(article.value);
  } else {
    //新增
    handleAdd();
  }
}

const handleClose = (done: () => void) => {};

/** 重置操作表单 */
function reset() {
  form.value = {
    categoryIdList: [],
    tagIdList: [],
    title: "",
    contentHtml: "",
    contentMd: "",
    articleId: "",
  };
  // proxy.resetForm("publishRef");
}

/** 新增按钮操作 */
function handleAdd() {
  reset();
  open.value = true;
  title.value = "添加文章";
}
/** 修改按钮操作 */
function handleUpdate(row) {
  reset();
  form.value = row;
  open.value = true;
  title.value = "修改文章";
}

/** 提交按钮 */
function submitForm() {
  console.log("form.value", form.value);
  getContent();
  if (form.value.articleId) {
    updateArticle(form.value).then((response) => {
      proxy.$modal.msgSuccess("修改成功");
      open.value = false;
    });
  } else {
    addArticle(form.value).then((response) => {
      proxy.$modal.msgSuccess("新增成功");
      open.value = false;
      console.log(`output->response`, response);
      form.value.articleId = response.data;
    });
  }
  saveSuccess();
}

const handleAddQuickSave = () => {
  submitForm();
};
const router = useRouter();

const handleClickPublish = () => {
  submitForm();
  router.push({ path: "article" });
};

//展示两秒成功
const saveSuccess = () => {
  isShowQuickSave.value = false;
  const timer = setTimeout(() => {
    isShowQuickSave.value = true;
    clearTimeout(timer);
  }, 2000);
};

const parentRef = ref<any>(null);
const draggableRef = ref<any>(null);
const dragX = ref(40); // 初始 X 位置
const dragY = ref(window.innerHeight * 0.4); // 初始 Y 位置，这里使用 window.innerHeight 的 40% 作为初始值，但你可能需要根据实际情况调整
let offsetX = 0; // 鼠标相对于元素左上角的 X 偏移
let offsetY = 0; // 鼠标相对于元素左上角的 Y 偏移
let dragging = false; // 是否正在拖动
let clickTimeout: any = null;
const handleMouseDown = (event) => {
  const startTime = Date.now();
  const startRect = draggableRef.value.getBoundingClientRect();

  // 开始拖动或等待点击
  startDrag(event);

  // 设置一个超时来检查是否是一个点击事件
  clickTimeout = setTimeout(() => {
    const endTime = Date.now();
    const endRect = draggableRef.value.getBoundingClientRect();

    // 检查是否是一个点击（没有拖动，且在短时间内释放）
    const isClick =
      !dragging &&
      Math.abs(startRect.left - endRect.left) < 5 && // 阈值可以根据需要调整
      Math.abs(startRect.top - endRect.top) < 5 &&
      endTime - startTime < 500; // 200毫秒内释放鼠标认为是点击

    if (isClick) {
      handleAddQuickSave();
    }

    // 清除超时引用
    clickTimeout = null;
  }, 200); // 稍微延迟一点来检查是否拖动
};
const startDrag = (event) => {
  dragging = true;
  offsetX = event.clientX - draggableRef.value.offsetLeft;
  offsetY = event.clientY - draggableRef.value.offsetTop;
  document.addEventListener("mousemove", onMouseMove);
  document.addEventListener("mouseup", onMouseUp);
};

const onMouseMove = (event) => {
  if (dragging) {
    const parentRect = parentRef.value.getBoundingClientRect();
    let newX = event.clientX - offsetX;
    let newY = event.clientY - offsetY;

    // 限制拖动范围在父元素内
    newX = Math.max(
      0,
      Math.min(parentRect.width - draggableRef.value.offsetWidth, newX)
    );
    newY = Math.max(
      0,
      Math.min(parentRect.height - draggableRef.value.offsetHeight, newY)
    );

    dragX.value = newX;
    dragY.value = newY;
  }
};

const onMouseUp = () => {
  dragging = false;
  document.removeEventListener("mousemove", onMouseMove);
  document.removeEventListener("mouseup", onMouseUp);
};

onMounted(() => {
  // 可以在这里添加任何需要在组件挂载后执行的逻辑
});

onUnmounted(() => {
  // 清理事件监听器，虽然在这个例子中它们会在组件卸载时自动失效，但这是一个好习惯
  document.removeEventListener("mousemove", onMouseMove);
  document.removeEventListener("mouseup", onMouseUp);
});

/** 取消按钮 */
function cancel() {
  open.value = false;
  reset();
}
onMounted(() => {
  init();
});
</script>

<style scoped>
.vditor-container {
  height: 100%;
  width: 100%;
  position: relative;
}
.quick-button {
  position: absolute;
  z-index: 1000;
  left: 40px;
  top: 40%;
}
</style>
